<template>
    <div class="chat-window-dialog">
        <div class="chat-list">
            <div class="chat-item" @click="emits('update:receiveId', item.user.id)"
                :class="{ active: receiveId == item.user.id }" :title="item.user.nickname" v-for="item in list"
                :key="item.id">
                <img class="avatar" :src="item.user.avatar || _defaultAvatar_" />
            </div>
        </div>
        <div class="chat-content">
            <div class="chat-header" ref="chatHeaderRef">
                <div class="title">
                    {{ receiveInfo.user ? receiveInfo.user.nickname : "" }}
                </div>

                <svg width="16" height="16" fill="none" xmlns="http://www.w3.org/2000/svg" class="icon-close"
                    viewBox="0 0 13 13" @click="onClose">
                    <path
                        d="M11.867 11.867a1.211 1.211 0 0 1-1.712 0l-3.71-3.71-3.711 3.71a1.211 1.211 0 1 1-1.713-1.712l3.71-3.71-3.71-3.711A1.21 1.21 0 1 1 2.734 1.02l3.71 3.71 3.71-3.71a1.211 1.211 0 0 1 1.713 1.713l-3.71 3.71 3.71 3.71c.473.474.473 1.24 0 1.713z"
                        fill="#ffffff" fill-opacity=".7"></path>
                </svg>
            </div>
            <div class="chat-body" ref="chatBodyRef" :style="{
                height: bodyHeight + 'px'
            }" @scroll="onScroll">
                <template v-for="item in receiveInfo.history" :key="item.id">
                    <div class="receive-item" v-if="item.send_id != userStore.userInfo.id">
                        <div class="avatar" @click="GoToPageHome(item.send_id)">
                            <img :src="receiveInfo.user.avatar || _defaultAvatar_" />
                        </div>

                        <div class="message" v-html="formatComment(item.message)"></div>

                        <div class="time">{{ handlerDate(item.createtime) }}</div>
                    </div>

                    <div class="send-item" v-if="item.send_id == userStore.userInfo.id">
                        <div class="time">{{ handlerDate(item.createtime) }}</div>
                        <div class="message" v-html="formatComment(item.message)"></div>
                        <div class="avatar">
                            <img :src="userStore.avatar || _defaultAvatar_" />
                        </div>
                    </div>
                </template>
            </div>

            <div class="chat-footer" ref="chatFooterRef">
                <div class="input-group" :class="{
                    'fixed': isInputLine
                }">

                    <div class="comment-box">
                        <div class="comment-input" ref="commentInputRef" :class="{
                            'input-line': isInputLine
                        }" contenteditable="true" @paste.prevent="onPaste($event)" @input="onInput($event)">
                        </div>

                        <div class="placeholder" v-show="!message">发送消息</div>
                    </div>

                    <div class="input-footer">
                        <EmojiPickerP :click-close="false" :icon="_oss_ + `images/icon-emoji-2.svg`" :size="30" :col="10"
                            :emojiText="false" @select-emoji="onSelectEmoji" />

                        <div class="send-btn">
                            <img :src="_oss_ + `images/${message ? 'icon-send-active' : 'icon-send'}.svg`"
                                @click="onSend" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { GetDialogueUserInfo, SendDialogueMessage } from "~/api";
import emojiList from "@/config/emoji.js";


const emits = defineEmits(['update:receiveId', 'close']);
const props = defineProps({
    list: {
        type: Array,
        default: () => ([])
    },
    receiveId: {
        type: Number,
        default: null
    }
})

const userStore = useUserStore();
const receiveInfo = ref({});
const commentInputRef = ref(null);
const chatHeaderRef = ref(null);
const chatBodyRef = ref(null);
const chatFooterRef = ref(null);
const isInputLine = ref(true);
const message = ref("");
const bodyHeight = ref(0);
let inputTimer = null;
let isScrollBottom = true;
let eventSource = null;

const getDialogInfo = async () => {
    const res = await GetDialogueUserInfo({ receive_id: props.receiveId });

    if (res.code == 200) {
        receiveInfo.value = res.data;

        onScrollBottom();
    }
}

const calcBodyHeight = () => {
    bodyHeight.value = 450 - chatHeaderRef.value.clientHeight - chatFooterRef.value.clientHeight;
    if (isScrollBottom) {
        onScrollBottom();
    }
}

const onInput = (e) => {
    if (inputTimer) clearTimeout(inputTimer);

    inputTimer = setTimeout(async () => {
        const height = e.target.clientHeight;
        const width = e.target.clientWidth;
        if (isInputLine.value) {
            isInputLine.value = height <= 42;
        } else {
            isInputLine.value = width <= 390;
        }

        message.value = e.target.innerText;

        await nextTick();
        // 计算body高度
        calcBodyHeight();
    })

}

const onClose = () => {
    emits('close');
    emits('update:receiveId', null);
    eventSource && eventSource.close();
}

const triggerInput = () => {
    let event = new Event('input', { bubbles: true, cancelable: true });
    commentInputRef.value.dispatchEvent(event);
}

const onSelectEmoji = (name) => {
    commentInputRef.value.innerText += `[${name}]`
    triggerInput();
}

const onPaste = (e) => {
    e.preventDefault();
    var text;
    var clp = (e.originalEvent || e).clipboardData;
    if (clp === undefined || clp === null) {
        text = window.clipboardData.getData("text") || "";
        if (text !== "") {
            if (window.getSelection) {
                var newNode = document.createElement("span");
                newNode.innerHTML = text;
                window.getSelection().getRangeAt(0).insertNode(newNode);
            } else {
                document.selection.createRange().pasteHTML(text);
            }
        }
    } else {
        text = clp.getData('text/plain') || "";
        if (text !== "") {
            document.execCommand('insertText', false, text);
        }
    }
}

const onScroll = () => {
    isScrollBottom = chatBodyRef.value.scrollTop + chatBodyRef.value.clientHeight >= chatBodyRef.value.scrollHeight - 5
}

const onScrollBottom = async () => {
    await nextTick();

    if (chatBodyRef.value) {
        chatBodyRef.value.scrollTop = chatBodyRef.value.scrollHeight;
    }
}

const initSSE = () => {
    eventSource = new EventSource('https://marketing.vrnewg.com/v1/dialogue/stream?send_id=' + userStore.userInfo.id + '&receive_id=' + props.receiveId);

    // 监听消息事件
    eventSource.onmessage = (event) => {
        const data = JSON.parse(event.data);
        if (receiveInfo.value) {
            receiveInfo.value.history.push(...data);
            onScrollBottom();
        }
    };

    // 连接成功事件
    eventSource.onopen = (event) => {
        console.log('连接已建立');
    };

    // 错误处理
    eventSource.onerror = (error) => {
        console.error('EventSource 发生错误:', error);
        eventSource.close(); // 手动关闭连接
        initSSE(); // 重新连接
    };
}

const onSend = async () => {
    if (message.value.length) {
        const res = await SendDialogueMessage({
            receive_id: props.receiveId,
            message: message.value
        });

        if (res.code == 200) {
            receiveInfo.value.history.push(res.data);

            onScrollBottom();

            commentInputRef.value.innerText = "";
            triggerInput();
        } else {
            Message().error("网络错误");
        }
    }
}

watch(() => props.receiveId, async () => {
    if (props.receiveId) {
        receiveInfo.value = {};
        await getDialogInfo();
        eventSource && eventSource.close();
        initSSE();
        calcBodyHeight();
    }
})

defineExpose({
    close: () => {
        onClose();
    }
})

const formatComment = (commentStr) => {
    for (let emoji of emojiList) {
        const reg = new RegExp(`\\[${emoji}\\]`, "g");
        commentStr = commentStr.replace(
            reg,
            `<img emoji-icon src='${_oss_}images/emoji/${emoji}.gif' />`
        );
    }
    return commentStr;
};

</script>
<style lang="scss" scoped>
.chat-window-dialog {
    position: fixed;
    bottom: 80px;
    right: 20px;
    background-color: rgba(0, 0, 0, .5);
    backdrop-filter: blur(20px);
    border-radius: 8px;
    z-index: 999;
    display: flex;
    height: 450px;

    .chat-list {
        width: 70px;
        height: 100%;
        display: flex;
        align-items: center;
        flex-direction: column;
        padding: 10px 0;
        border-right: 1px solid rgba(255, 255, 255, .1);
        overflow: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;

        &::-webkit-scrollbar {
            display: none;
        }

        .chat-item {
            padding: 5px;
            border-radius: 10px;
            margin-bottom: 5px;
            cursor: pointer;

            &.active {
                background-color: rgba(255, 255, 255, .1);
            }

            .avatar {
                width: 40px;
                height: 40px;
                border-radius: 50%;
                object-fit: cover;
                flex-shrink: 0;
                display: block;
            }
        }
    }

    .chat-content {
        position: relative;
        width: 450px;

        .chat-header {
            display: flex;
            align-items: center;
            height: 50px;
            padding: 0 10px;
            color: #fff;

            .title {
                font-size: 18px;
            }

            .icon-close {
                margin-left: auto;
                cursor: pointer;
            }
        }

        .chat-body {
            padding: 10px;
            overflow: auto;
            scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
            scrollbar-width: thin;

            .receive-item,
            .send-item {
                display: flex;
                align-items: flex-start;
                margin-bottom: 20px;
            }

            .avatar {
                width: 36px;
                height: 36px;
                border-radius: 50%;
                overflow: hidden;
                cursor: pointer;

                img {
                    width: 100%;
                    height: 100%;
                    object-fit: cover;
                }
            }

            .time {
                font-size: 12px;
                color: rgba(255, 255, 255, 0.6);
            }

            .message {
                position: relative;
                max-width: 250px;
                padding: 8px;
                border-radius: 6px;
                line-height: 20px;
                word-wrap: break-word;
                word-break: break-all;

                :deep(img[emoji-icon]) {
                    width: 20px;
                    vertical-align: top;
                }
            }

            .receive-item {
                .message {
                    background: #F4F4F4;
                    color: #000;
                    font-size: 14px;
                    margin-left: 10px;
                }

                .time {
                    margin-left: 8px;
                }
            }

            .send-item {
                justify-content: flex-end;

                .message {
                    font-size: 14px;
                    color: #FFFFFF;
                    background-color: #5085FB;
                    margin-right: 10px;
                }

                .time {
                    padding-right: 8px;
                }
            }
        }

        .chat-footer {
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            border-top: 1px solid rgba(255, 255, 255, .1);
            padding: 10px 15px;

            .input-group {
                position: relative;
                width: 100%;
                background-color: rgba(255, 255, 255, .1);
                border-radius: 10px;

                &.fixed {
                    .comment-box {
                        width: calc(100% - 80px);
                    }

                    .input-footer {
                        position: absolute;
                        top: 50%;
                        right: 0;
                        transform: translateY(-50%);
                        padding: 0;
                    }
                }

                .comment-box {
                    position: relative;
                    width: 100%;

                    .placeholder {
                        position: absolute;
                        top: 50%;
                        left: 10px;
                        color: rgba(255, 255, 255, 0.6);
                        transform: translateY(-50%);
                        font-size: 14px;
                        line-height: 22px;
                    }

                    .comment-input {
                        display: inline-block;
                        max-width: 100%;
                        min-width: 200px;
                        max-height: 86px;
                        line-height: 22px;
                        padding: 10px 10px;
                        color: #fff;
                        font-size: 14px;
                        outline: none;
                        user-select: text;
                        white-space: pre-wrap;
                        overflow-wrap: break-word;
                        overflow: auto;
                    }
                }

                .input-footer {
                    display: flex;
                    justify-content: flex-end;
                    padding: 0 0 10px;

                    .send-btn {
                        position: relative;
                        width: 24px;
                        height: 24px;
                        margin: 0 10px;
                        cursor: pointer;

                        img {
                            position: absolute;
                            left: -6px;
                            top: -6px;
                            width: 36px;
                            height: 36px;
                        }
                    }
                }
            }
        }

    }
}
</style>